package com.cloud.servicezuul.compoment;

import com.cloud.servicezuul.entity.GreySetting;
import com.cloud.servicezuul.entity.OnlineSetting;
import com.cloud.servicezuul.service.GreyReleaseService;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import io.jmnarloch.spring.cloud.ribbon.support.RibbonFilterContextHolder;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

@Component
public class GreyFilter extends ZuulFilter {

    @Value("${zuul.prefix}")
    private String prefix;

    @Autowired
    private ZuulProperties zuulProperties;

    @Autowired
    private GreyReleaseService releaseService;

    @Override
    public String filterType() {
        return FilterConstants.ROUTE_TYPE;
    }

    @Override
    public int filterOrder() {
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() {

        //获取请求上下文，目的是拿到用户的信息
        RequestContext currentContext = RequestContext.getCurrentContext();
        //是否还继续往后路由 后面的过滤器需要 currentContext.sendZuulResponse()配合
        //currentContext.setSendZuulResponse(false);

        HttpServletRequest request = currentContext.getRequest();
        String serviceName = getServiceName(request.getRequestURI());
        String userId = request.getHeader("userId");

        if (StringUtils.isBlank(userId))return null;

        //查询这个用户是否有对应的灰度发布的版本
        GreySetting greySetting = releaseService.queryGreySettingByUserIdAndServiceName(userId, serviceName);

        //如果有对应的灰度发布的版本，则请求该版本
        if (greySetting != null) {
            //用这个，需要引入一个第三方的starter  ribbon-discovery-filter-spring-cloud-starter
            RibbonFilterContextHolder.getCurrentContext().add("version", greySetting.getVersion());
        } else {
            OnlineSetting onlineSetting = releaseService.queryOnLineSetting(serviceName);
            if (onlineSetting != null) {
                RibbonFilterContextHolder.getCurrentContext().add("version", onlineSetting.getVersion());
            }
        }

        return null;
    }

    private String getServiceName(String uri) {
        //如果路由配置了前缀，那么在获取服务名称的时候，需要把前缀给去掉
        if (StringUtils.isNotBlank(prefix)) {
            uri = uri.replace(prefix, "");
        }
        if (uri.startsWith("/")) {
            uri = uri.substring(1);
        }
        uri = uri.split("/")[0];
        //如果配置了静态路由，那么根据路由规则，转换成实际的serviceName
        String finalUri = uri;
        Map<String, String> map = zuulProperties.getRoutes().values().stream().
                filter(zuulRoute -> zuulRoute.getPath().contains(finalUri)).collect(Collectors.toMap(ZuulProperties.ZuulRoute::getPath, ZuulProperties.ZuulRoute::getUrl));

        if (map.size() > 0){
            Optional<String> optional = map.values().stream().distinct().findFirst();
            if (optional.isPresent()){
                return optional.get();
            }
        }
        return uri;
    }
}
